#!/bin/bash
##############################################################################
# 脚本功能：清理系统缓存 + 完全重启Docker（含socket） + 确保指定容器启动
# 修复点：移除timeout命令，使用更安全的服务管理方式
##############################################################################

# 1. 基础配置
LOG_FILE="/var/log/docker_restart_clean.log"
TARGET_CONTAINERS="fastapi-backend frontend_frontend_1"
MAX_RETRIES=3

# 2. 日志函数
log() {
    local level="INFO"
    if [[ "$1" == "ERROR" || "$1" == "WARNING" ]]; then
        level="$1"
        shift
    fi
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $1" | tee -a "$LOG_FILE"
    if [[ "$level" == "ERROR" ]]; then
        echo "错误: $1" >&2
    fi
}

# 3. 检查命令执行状态
check_cmd() {
    if [ $? -eq 0 ]; then
        log "$1 成功"
        return 0
    else
        log "ERROR" "$1 失败"
        return 1
    fi
}

# 4. 容器启动函数
start_container() {
    local container_name="$1"
    local retry_count=0
    
    if ! docker inspect "$container_name" &>/dev/null; then
        log "WARNING" "容器 $container_name 不存在，跳过"
        return 1
    fi
    
    local status=$(docker inspect -f '{{.State.Status}}' "$container_name" 2>/dev/null)
    
    if [ "$status" = "running" ]; then
        log "容器 $container_name 已运行"
        return 0
    fi
    
    log "启动容器 $container_name（当前状态：$status）..."
    
    while [ $retry_count -lt $MAX_RETRIES ]; do
        if docker start "$container_name" &>/dev/null; then
            sleep 2
            local new_status=$(docker inspect -f '{{.State.Status}}' "$container_name" 2>/dev/null)
            if [ "$new_status" = "running" ]; then
                log "容器 $container_name 启动成功（尝试 $((retry_count+1)) 次）"
                return 0
            fi
        fi
        
        retry_count=$((retry_count+1))
        log "WARNING" "容器 $container_name 启动失败，第 $retry_count 次重试..."
        sleep 3
    done
    
    log "ERROR" "容器 $container_name 启动失败（最大重试次数 $MAX_RETRIES）"
    return 1
}

# 5. 内存使用情况报告
report_memory() {
    local mem_info=$(free -h | awk '/Mem:/ {printf "内存: 已用=%s, 可用=%s, 缓存/缓冲=%s", $3, $7, $6}')
    log "$1 - $mem_info"
}

# 6. 安全停止服务（修复版）
safe_stop_service() {
    local service_name="$1"
    
    if systemctl is-active --quiet "$service_name"; then
        log "停止 $service_name ..."
        systemctl stop "$service_name"
        sleep 2
        
        # 检查是否真正停止
        local wait_count=0
        while [ $wait_count -lt 5 ]; do
            if ! systemctl is-active --quiet "$service_name"; then
                log "$service_name 停止成功"
                return 0
            fi
            wait_count=$((wait_count+1))
            sleep 1
        done
        
        log "WARNING" "$service_name 停止缓慢，尝试强制检查"
        return 0
    else
        log "$service_name 未运行，无需停止"
        return 0
    fi
}

# 7. 安全启动服务
safe_start_service() {
    local service_name="$1"
    
    log "启动 $service_name ..."
    if systemctl start "$service_name"; then
        sleep 3
        
        local wait_count=0
        while [ $wait_count -lt 10 ]; do
            if systemctl is-active --quiet "$service_name"; then
                log "$service_name 启动成功"
                return 0
            fi
            sleep 1
            wait_count=$((wait_count+1))
        done
        
        log "WARNING" "$service_name 启动较慢，但已发出启动指令"
        return 0
    else
        log "ERROR" "$service_name 启动失败"
        return 1
    fi
}

# 8. 检查Docker就绪状态
check_docker_ready() {
    local retry_count=0
    while [ $retry_count -lt 10 ]; do
        if docker info &>/dev/null; then
            log "Docker服务就绪"
            return 0
        fi
        retry_count=$((retry_count+1))
        sleep 2
    done
    log "ERROR" "Docker服务未就绪"
    return 1
}

# 9. 主任务执行
main() {
    log "==================================== 任务开始 ===================================="
    report_memory "初始状态"
    
    # 1. 清理系统缓存
    log "清理系统缓存..."
    if echo 3 > /proc/sys/vm/drop_caches 2>/dev/null; then
        log "缓存清理成功"
        sleep 2
        report_memory "缓存清理后"
    else
        log "WARNING" "缓存清理失败（可能已无缓存可清理）"
    fi
    
    # 2. 完全重启Docker
    log "开始完全重启Docker服务..."
    
    # 停止服务
    safe_stop_service "docker.socket"
    safe_stop_service "docker.service"
    
    # 确保Docker进程完全退出
    if pgrep dockerd >/dev/null; then
        log "WARNING" "Docker进程仍在运行，等待自然退出..."
        sleep 5
        if pgrep dockerd >/dev/null; then
            log "WARNING" "Docker进程仍未退出，继续执行"
        fi
    fi
    
    # 启动服务
    safe_start_service "docker.socket"
    safe_start_service "docker.service"
    
    log "等待Docker初始化完成..."
    check_docker_ready
    
    # 3. 启动目标容器
    log "检查并启动目标容器..."
    for container in $TARGET_CONTAINERS; do
        start_container "$container"
    done
    
    # 4. 最终状态验证
    log "验证最终状态..."
    if systemctl is-active --quiet docker && systemctl is-active --quiet docker.socket; then
        log "Docker服务与socket均正常运行"
    else
        log "WARNING" "Docker服务或socket状态异常"
    fi
    
    # 检查容器最终状态
    for container in $TARGET_CONTAINERS; do
        if docker inspect "$container" &>/dev/null; then
            status=$(docker inspect -f '{{.State.Status}}' "$container" 2>/dev/null)
            log "容器 $container 最终状态: $status"
        fi
    done
    
    report_memory "最终状态"
    log "==================================== 任务完成 ===================================="
}

# 执行主函数
main "$@"